16. PΩtle |
PΩtle s▒ bardzo u┐ytecznym elementem jΩzyka JavaScript (innych r≤wnie┐ :). Pozwalaj▒ one na wykonywanie zawartych w nich polece± wielokrotnie, przez co zmniejsza siΩ objΩto╢µ kodu skryptu, a zarazem oszczΩdza pracy programi╢cie. W jΩzyku JavaScript (w wersji 5.5) istniej▒ 3 rodzaje pΩtli oraz stosowanie tzw. etykietek, kt≤re nie s▒ uznawane za iteracjΩ (pΩtlΩ), jednak┐e ich u┐ywanie g│≤wnie do takiej funkcji siΩ sprowadza.
Pierwsz▒ pΩtl▒ jest pΩtla for. Jej sk│adnia wygl▒da nastΩpuj▒co:
for ([warto╢µ pocz▒tkowa licznika]; [warunek]; [zmiana licznika])
{
... polecenia;
... polecenia;
}
WystΩpuje tutaj taka zmienna, jak licznik pΩtli. Jego warto╢µ pocz▒tkow▒ ustawiamy w polu warto╢µ pocz▒tkowa
. Zazwyczaj identyfikuje on liczbΩ przebieg≤w pΩtli, zwiΩkszan▒ w miejscu zmiana licznika
. Licznik mo┐e byµ r≤wnie┐ dekrementowany (zmniejszany) i wtedy pΩtla wykonuje siΩ jakby od ko±ca do pocz▒tku.
Struktura dzia│ania pΩtli wygl▒da nastΩpuj▒co:
true
to pΩtla bΩdzie chodziµ dalej, a je┐eli wynosi false
- pΩtla zostaje przerwana
Mo┐liwe jest zagnie┐d┐anie jednej pΩtli w drugiej, to znaczy umieszczenie jednej pΩtli w bloku drugiej. Jest to czΩsto wykorzystywane przy obs│udze wielowymiarowych tablic.
Oto przyk│ad wykorzystania pΩtli for:
<SCRIPT LANGUAGE="JavaScript">
<!--
function potega()
{
var wynik = 1;
l = parseInt(document.forms["matma"].podstawa.value);
w = parseInt(document.forms["matma"].wykladnik.value);
for (i = 1; i <= w; i++)
{
wynik *= l;
}
window.alert("Wynik to: " + wynik);
}
//-->
</SCRIPT>
.. i jeszcze potrzebne elementy formularza:
<FORM name="matma">
<INPUT TYPE="text" VALUE=2 SIZE=2 name="podstawa"> do potΩgi
<INPUT TYPE="text" VALUE=3 SIZE=2 name="wykladnik">
<INPUT TYPE="button" VALUE="Oblicz" onClick="potega()">
</FORM>
Oraz efekt dzia│ania:
Kolejna pΩtla do..while r≤┐ni siΩ tym od poprzedniej, ┐e nie posiada ona licznika pΩtli. Podobnie zreszt▒ pΩtla while. Niekt≤rzy uwa┐aj▒ obie powy┐sze jako jedn▒ i t▒ sam▒. Ze wzglΩdu na zasadnicz▒ r≤┐nicΩ w dzia│aniu (mimo podobnej sk│adni i u┐ytych s│≤w kluczowych), wiele os≤b rozr≤┐nia je jako dwie osobne. R≤┐nica polega na tym, ┐e w pierwszym przypadku pΩtla sprawdza warunek po wykonaniu siΩ instrukcji, natomiast w drugim przypadku - przed. Obie pΩtle wykonuj▒ siΩ tak d│ugo, jak d│ugo podany warunek jest prawdziwy (ma warto╢µ logiczn▒ true
).
Sk│adnia pΩtli do...while:
do
{
... polecenie;
... polecenie;
}
while (warunek);
Przepiszmy funkcjΩ potega() u┐ywaj▒c tej w│a╢nie pΩtli:
function potega2()
{
var wynik = 1;
l = parseInt(document.forms["matma"].podstawa.value);
w = parseInt(document.forms["matma"].wykladnik.value);
i = 1
do
{
wynik *= l;
i++;
}
while (i <= w);
window.alert("Wynik to: " + wynik);
}
Widzimy, ┐e mimo wszystko musieli╢my zadeklarowaµ sobie sw≤j licznik pΩtli, zatem zauwa┐amy, ┐e wyb≤r odpowiedniej pΩtli zale┐y od algorytmu. Nie jest oczywi╢cie b│Ωdem, stosowanie ca│y czas jednej pΩtli, jednak stosowanie r≤┐nych pΩtli w r≤┐nych sytuacjach na pewno u│atwi nam ┐ycie.
Tak wygl▒da sk│adnia pΩtli while:
while (warunek)
{
... polecenie;
... polecenie;
}
A funkcja potega() przepisana z u┐yciem pΩtli while:
function potega3()
{
var wynik = 1;
l = parseInt(document.forms["matma"].podstawa.value);
w = parseInt(document.forms["matma"].wykladnik.value);
i = 1
while (i <= w)
{
wynik *= l;
i++;
}
window.alert("Wynik to: " + wynik);
}
W tym przypadku nie widaµ r≤┐nicy miΩdzy obiema pΩtlami, poniewa┐ wykonywane polecenia nie zale┐▒ od licznika pΩtli. Jednak na przyk│ad przy u┐yciu pΩtli do tablicy zauwa┐ymy odmienno╢µ dzia│ania tych pΩtli.
Pocz▒wszy od wersji 5 JavaScript, mo┐liwe jest u┐ywanie takiej pΩtli jak for...in. PΩtla wykonuje polecenia dla ka┐dej w│asno╢ci obiektu lub elementu tablicy. Sk│adnia:
for (warto╢µ in [ obiekt | tablica ])
{
... polecenie;
... polecenie;
}
Nale┐y pamiΩtaµ, ┐e nie ma mo┐liwo╢ci ustalenia kierunku wykonywania siΩ pΩtli. Warto╢µ jest zmieniana zawsze na nastΩpn▒ (nie mo┐na zmieniµ na poprzedni▒).
Czy zwr≤ci│e╢ uwagΩ na fakt, ┐e w deklaracji pΩtli for u┐y│em nawias≤w kwadratowych przy inicjacji licznika, warunku dzia│ania pΩtli oraz warto╢ci zmiany licznika? Zatem pominiΩcie ich i napisanie czego╢ takiego, nie wywo│a b│Ωdu:
for (;;)
{
... Polecenie;
... Polecenie;
}
Zastanawiasz siΩ jak zachowa siΩ przegl▒darka interpretuj▒ca taki skrypt, a zachowa siΩ dok│adnie tak samo jak podczas wykonywania pΩtli while, w kt≤rej warunek jest ca│y czas prawdziwy (np.: 1==1
). Skoro taka pΩtla siΩ nigdy nie ko±czy, to po co jej u┐ywaµ, je╢li ma doprowadziµ do zawieszenia przegl▒darki, tudzie┐ Explorera (Internet Explorer ma zabezpieczenie na tak▒ ewentualno╢µ i pozwala wy│▒czyµ aplet, kt≤ry znacznie spowalnia jego pracΩ).
PΩtlΩ mo┐na przerwaµ za pomoc▒ instrukcji break
, poznanej w lekcji o instrukcji switch. Polecenia w pΩtli znajduj▒ce siΩ za break
nie zostan▒ wykonane. Przeanalizujmy taki przyk│ad:
for (;;)
{
odp = prompt("Podaj has│o dostΩpu:");
if (odp == "nikomu_nie_znane_has│o") then break;
alert("Niestety! Poda│e╢ nieprawid│owe has│o.");
}
Je┐eli u┐ytkownik poda nieprawid│owe has│o, to wy╢wietli mu siΩ na ekranie stosowny komunikat, natomiast po wpisaniu prawid│owego has│a, przegl▒darka przeskoczy do linii znajduj▒cych siΩ zaraz za pΩtl▒, nie wy╢wietlaj▒c komunikatu.
U┐ytecznym poleceniem jest continue, kt≤re umieszczone w pΩtli przekazuje jej dzia│anie na pocz▒tek, zmieniaj▒c licznik zgodnie z deklaracj▒. S│u┐y to zwiΩkszeniu szybko╢ci algorytmu, poniewa┐ polecenia za continue nie s▒ wykonywane. Zobaczmy to na przyk│adzie:
function przykl_continue()
{
for (i = 1; i <= 10; i++)
{
if (i % 2 == 0) continue;
alert("To jest " + i + " przebieg pΩtli");
}
}
Widzimy, ┐e wy╢wietlane s▒ komunikaty dla nieparzystych index≤w pΩtli. Dla parzystych (reszta z dzielenia % przez 2 wynosi zero, zob. [operatory]) index≤w pΩtla przeskakuje na sw≤j pocz▒tek.
Sporadycznie u┐ywa siΩ zamiennie z prawdziwymi pΩtlami tzw. etykietek (od ang. label - etykieta). Dekalruje siΩ je tak:
label:
{
... Polecenie;
... Polecenie;
}
W miejsce "label" wstawiamy tekst identyfikuj▒cy etykietkΩ. Aby teraz zapΩtliµ skrypt oraz wyj╢µ z iteracji, u┐ywa siΩ instrukcji continue i break:
start:
{
... Polecenie;
... Polecenie;
if (warunek wyjscia) break start;
continue start;
}
Osobi╢cie bardzo odradzam stosowania etykietek na rzecz innych pΩtli, kt≤re s▒ czytelniejsze, wygodniejsze i trudniej siΩ w nich pogubiµ.
TrochΩ siΩ rozpisa│em, ale pΩtle s▒ tymi elementami jΩzyka JavaScript, kt≤rych bedziesz u┐ywa│ bardzo czΩsto, wiΩc dobrze jest w tym temacie dok│adnie wiedzieµ "co i jak".
![]() ![]() ![]() |